package com.binarytree;

import lombok.Data;

@Data
public class HeroNode {
    private int no;
    private String name;
    private HeroNode left;
    private HeroNode right;

    public HeroNode(int no, String name) {
        this.no = no;
        this.name = name;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }


    /**
     * 前序遍历：中-左-右
     */
    public void preOrder() {
        //先输出当前节点
        System.out.println(this);
        //左子树非空则递归
        if (this.left != null) {
            this.left.preOrder();
        }
        //右子数非空则递归
        if (this.right != null) {
            this.right.preOrder();
        }
    }

    /**
     * 中序遍历：左-中-右
     */
    public void infixOrder() {
        if (this.left != null) {
            this.left.infixOrder();
        }
        System.out.println(this);
        if (this.right != null) {
            this.right.infixOrder();
        }
    }

    /**
     * 后序遍历：左-右-中
     */
    public void postOrder() {
        if (this.left != null) {
            this.left.postOrder();
        }
        if (this.right != null) {
            this.right.postOrder();
        }
        System.out.println(this);
    }

    /**
     * 前序查找
     * @return
     */
    public HeroNode preOrderSearch(int no) {
        //比较当前节点，如果是则返回当前节点
        if (this.no == no) {
            return this;
        }
        //如果不是
        //则先判断左节点是否为空，不为空则进行对左节点进行前序递归
        //辅助节点用于保存查询的结果
        HeroNode resNode = null;
        if (this.left != null) {
            resNode = this.left.preOrderSearch(no);
        }
        //左递归直到当前左节点为空
        if (resNode != null) {
            return resNode;
        }
        //如果右节点不为空，右节点进行右递归
        if (this.right != null) {
            resNode = this.right.preOrderSearch(no);
        }
        return resNode;
    }

    /**
     * 中序查找
     */
    public HeroNode infixOrderSearch(int no) {
        HeroNode resNode = null;
        if (this.left != null) {
            resNode = this.left.infixOrderSearch(no);
        }
        if (resNode != null) {
            return resNode;
        }
        //在左子树中都没有找到就判断当前节点
        if (this.no == no) {
            return this;
        }
        //右节点
        if (this.right != null) {
            resNode = this.right.infixOrderSearch(no);
        }
        return resNode;
    }

    /**
     * 后续查找
     */
    public HeroNode postOrderSearch(int no){
        HeroNode resNode = null;
        if (this.left != null) {
            resNode = this.left.postOrderSearch(no);
        }
        if (resNode != null) {
            return resNode;
        }
        if (this.right != null) {
            resNode = this.right.infixOrderSearch(no);
        }
        if (resNode != null) {
            return resNode;
        }
        //在左子树中都没有找到就判断当前节点
        if (this.no == no) {
            return this;
        }
        //右节点
        return resNode;
    }

    /**
     * 递归删除节点
     * 如果是叶子节点，则直接删除该节点
     * 如果非叶子节点，删除以该节点为父节点的子树
     */
    public void deleteNode(int no){
        //判断当前节点左节点是否为空，是否为要删除的结点
        if(this.left != null && this.left.no == no){
            this.left = null;
        }
        //判断当前节点右节点是否为空，是否为要删除的结点
        if(this.right != null && this.right.no == no){
            this.right = null;
        }
        //如果当前节点的左右子节点都不是要查找的结点，就左递归
        if(this.left!=null){
            this.left.deleteNode(no);
        }
        //所有的左子树上没找到就进行右递归
        if(this.right!=null){
            this.right.deleteNode(no);
        }
    }
}
